package daybook.model;

import daybook.annotation.Bean;
import org.immutables.value.Value;

import java.util.Collections;
import java.util.Optional;
import java.util.Set;

@Bean
@Value.Immutable
public abstract class Account {
    public enum Type {
        ASSET(DC.DEBIT),
        EQUITY(DC.CREDIT),
        LIABILITY(DC.CREDIT),
        REVENUE(DC.CREDIT),
        EXPENSE(DC.DEBIT);

        private final int normalBalance;

        Type(int normalBalance) {
            this.normalBalance = normalBalance;
        }

        public int getNormalBalance() {
            return normalBalance;
        }
    }

    public abstract String getCode();
    public abstract String getName();
    public abstract Optional<Commodity> getCommodity();
    public abstract Type getType();

    @Value.Default
    public Set<String> getAttributes() {
        return Collections.emptySet();
    }

    @Value.Default
    public Set<String> getAliases() {
        return Collections.emptySet();
    }

    @Value.Default
    public String getParentCode() {
        return ROOT.getCode();
    }

    @Value.Default
    public String getDescription() {
        return "";
    }

    public static final Account ROOT = new Account() {
        private static final String ROOT_ACCOUNT_CODE = "*ROOT*";
        @Override
        public String getCode() {
            return ROOT_ACCOUNT_CODE;
        }

        @Override
        public String getName() {
            return null;
        }

        @Override
        public Type getType() {
            return null;
        }

        @Override
        public Optional<Commodity> getCommodity() {
            return Optional.empty();
        }

        @Override
        public String getParentCode() {
            return null;
        }

        @Override
        public boolean equals(Object obj) {
            return this == obj;
        }

        @Override
        public String toString() {
            return ROOT_ACCOUNT_CODE;
        }
    };
}